Implement LWG 2148: Make non-enum default hash specialization well-formed Summary: This patch removes the static_assert for non-enum types in the primary hash template. Instead non-enum types create a hash<T> specialization that is not constructible nor callable. See also: * http://cplusplus.github.io/LWG/lwg-active.html#2543 * https://llvm.org/bugs/show_bug.cgi?id=28917 Reviewers: mclow.lists, EricWF Subscribers: mehdi_amini, cfe-commits Differential Revision: https://reviews.llvm.org/D23331 git-svn-id: https://llvm.org/svn/llvm-project/libcxx/trunk@278300 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/include/functional b/include/functional index 2056ffe..db137d1 100644 --- a/include/functional +++ b/include/functional
@@ -2574,12 +2574,11 @@ }; #if _LIBCPP_STD_VER > 11 -template <class _Tp> -struct _LIBCPP_TYPE_VIS_ONLY hash + +template <class _Tp, bool = is_enum<_Tp>::value> +struct _LIBCPP_TYPE_VIS_ONLY __enum_hash : public unary_function<_Tp, size_t> { - static_assert(is_enum<_Tp>::value, "This hash only works for enumeration types"); - _LIBCPP_INLINE_VISIBILITY size_t operator()(_Tp __v) const _NOEXCEPT { @@ -2587,6 +2586,17 @@ return hash<type>{}(static_cast<type>(__v)); } }; +template <class _Tp> +struct _LIBCPP_TYPE_VIS_ONLY __enum_hash<_Tp, false> { + __enum_hash() = delete; + __enum_hash(__enum_hash const&) = delete; + __enum_hash& operator=(__enum_hash const&) = delete; +}; + +template <class _Tp> +struct _LIBCPP_TYPE_VIS_ONLY hash : public __enum_hash<_Tp> +{ +}; #endif